﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace GDD2_Game3
{
    class Vehicle:GameObject
    {
        //attributes
        private Vector2 velocity;
        private Vector2 unitVelocity;

        private const float ACCELERATION_FOR_ACCELERATION_BUTTON = 200.0f;
        private const float ACCELERATION_FOR_DECCELERATION_BUTTON = -200.0f;
        private const float FRIC = 50.0f;

        private const float ACCELERATION_BY_CRASH = -1000.0f;

        private const float TURN_RIGHT = 200.0f;
        private const float TURN_LEFT = -200.0f;

        public Vehicle(float x, float y, float width, float height)
            :base(x, y, width, height)
        {
            velocity = new Vector2(0, 0);
            unitVelocity = new Vector2(0, 0);
        }

        private void accelerate(float dv, float deltaTime, bool byDirection, bool byVelocity)
        {
            if (byDirection)
            {
                velocity += dv * deltaTime * direction;
            }
            if (byVelocity)
            {
                velocity += dv * deltaTime * unitVelocity;
            }
        }

        private void turn(float degreeOfTurn)
        {
            rotation += MathHelper.ToRadians(degreeOfTurn);
            direction.X = (float)Math.Cos((double)rotation);
            direction.Y = (float)Math.Sin((double)rotation);
        }

        private float Dotp(Vector2 v1, Vector2 v2)
        {
            float v3;

            v3 = (v1.X * v2.X) + (v1.Y * v2.Y);

            return v3;
        }

        public void move(bool isTurningLeft, bool isTurningRight, bool acceleratingFoward, bool acceleratingBackward, List<Wall> crashedInto, float deltaTime)
        {
            if (acceleratingFoward && Dotp(direction, velocity) >= 0)
            {
                accelerate(ACCELERATION_FOR_ACCELERATION_BUTTON, deltaTime, true, false);
            }
            else if (acceleratingFoward && Dotp(direction, velocity) < 0)
            {
                accelerate(ACCELERATION_FOR_DECCELERATION_BUTTON, deltaTime, false, true);
            }
             
            if (acceleratingBackward && Dotp(direction, velocity) <= 0)
            {
                accelerate(ACCELERATION_FOR_ACCELERATION_BUTTON, deltaTime, true, false);
            }
            else if (acceleratingBackward && Dotp(direction, velocity) > 0)
            {
                accelerate(ACCELERATION_FOR_DECCELERATION_BUTTON, deltaTime, false, true);
            }

            if (!acceleratingFoward && !acceleratingBackward && Dotp(direction, velocity) < 0)
            {
                accelerate(FRIC, deltaTime, false, true);

                if (velocity.Length() <= FRIC)
                {
                    velocity = Vector2.Zero;
                }
            }

            if (!acceleratingFoward && !acceleratingBackward && Dotp(direction, velocity) > 0)
            {
                accelerate(-(FRIC), deltaTime, false, true);

                if (velocity.Length() <= FRIC)
                {
                    velocity = Vector2.Zero;
                }
            }

            if (isTurningLeft)
            {
                turn(TURN_LEFT * deltaTime);
            }
            if (isTurningRight)
            {
                turn(TURN_RIGHT * deltaTime);
            }

           

            /*foreach (Wall wall in crashedInto)
            {
                FloatBox.IntersectionInformation intersectInfo = Box.intersects(wall.Box);
                Vector2 bounce = bounceUnit(intersectInfo);
                Vector2 velMult = new Vector2(bounce.X < 0.0f ? -0.25f : 1.0f, bounce.Y < 0.0f ? -0.25f : 1.0f);
                velocity *= velMult;
                if(velMult != Vector2.One) Console.WriteLine(intersectInfo.ToString());
                if (intersectInfo.OtherAbove)
                {
                    box = new FloatBox(new Vector2(wall.Box.Position.X, wall.Box.Position.Y + (wall.Box.Height + Box.Height) / 2.0f), Box.Dimensions);
                }
                if (intersectInfo.OtherBelow)
                {
                    box = new FloatBox(new Vector2(wall.Box.Position.X, wall.Box.Position.Y - (wall.Box.Height + Box.Height) / 2.0f), Box.Dimensions);
                }
                if (intersectInfo.OtherToLeft)
                {
                    box = new FloatBox(new Vector2(wall.Box.Position.X + (wall.Box.Width + Box.Width) / 2.0f, wall.Box.Position.Y), Box.Dimensions);
                }
                if (intersectInfo.OtherToRight)
                {
                    box = new FloatBox(new Vector2(wall.Box.Position.X - (wall.Box.Width + Box.Width) / 2.0f, wall.Box.Position.Y), Box.Dimensions);
                }
            }*/
            
			if(crashedInto.Count != 0)
			{
				foreach(Wall wall in crashedInto)
				{
                    if (box.intersects(wall.Box))
                    {
                        //Console.WriteLine(box.intersects(wall.Box).);
                    }
					if(Box.intersects(wall.Box).OtherAbove)
					{
						box.Position.Y = wall.Box.Position.Y + ((box.Height + wall.Box.Height) / 2);
                        velocity *= 0;
					}
					if(Box.intersects(wall.Box).OtherBelow)
                    {
                        box.Position.Y = wall.Box.Position.Y - ((box.Height + wall.Box.Height) / 2);
                        velocity *= 0;
                    }
					if(Box.intersects(wall.Box).OtherToLeft)
                    {
                        box.Position.X = wall.Box.Position.X + ((box.Width + wall.Box.Width) / 2);
                        velocity *= 0;
                    }
					if(Box.intersects(wall.Box).OtherToRight)
                    {
                        box.Position.X = wall.Box.Position.X - ((box.Width + wall.Box.Width) / 2);
                        velocity *= 0;
                    }
				}
			}

            unitVelocity = velocity / velocity.Length();
            box += velocity * deltaTime;
        }
    }
}
